using System.Windows;

namespace Bookvar.ObjectModel.Actions
{
    public class ChangeTopicPositionByOffsetAction : MindmapTopicActionBase
    {
        private readonly bool moveChildren;
        private readonly Point offset;


        public ChangeTopicPositionByOffsetAction( Topic topic, Point offset, MindMap mindmap, bool moveChildren )
            : this( topic, offset, mindmap )
        {
            this.moveChildren = moveChildren;
        }

        public ChangeTopicPositionByOffsetAction( Topic topic, Point offset, MindMap mindmap ) : base( topic, mindmap )
        {
            this.offset = offset;
        }

        public override void Execute()
        {
            base.Execute();

            if ( moveChildren )
            {
                ApplyOffsetRecursive( Topic, offset, Mindmap );
            }
            else
            {
                ApplyOffset( Topic, offset, Mindmap );
            }
        }

        public override void Undo()
        {
            base.Undo();

            var negativeOffset = new Point( -offset.X, -offset.Y );

            if ( moveChildren )
            {
                ApplyOffsetRecursive( Topic, negativeOffset, Mindmap );
            }
            else
            {
                ApplyOffset( Topic, negativeOffset, Mindmap );
            }
        }

        private static void ApplyOffsetRecursive( Topic topic, Point offset, MindMap mindMap )
        {
            ApplyOffset( topic, offset, mindMap );

            if ( topic.SubTopics.Count > 0 )
            {
                foreach ( Topic child in topic.SubTopics )
                {
                    ApplyOffsetRecursive( child, offset, mindMap );
                }
            }
        }

        private static void ApplyOffset( Topic topic, Point offset, MindMap mindMap )
        {
            TopicPosition position;
            if ( !mindMap.TopicPositions.TryGetItem( topic.ID, out position ) )
            {
                position = new TopicPosition( topic.ID );
                mindMap.TopicPositions.Add( position );
            }

            position.X += offset.X;
            position.Y += offset.Y;
            position.IsMoved = true;
        }
    }
}